package com.example.mysql.学习笔记.高级.事务.锁;

public class MySQL并发事务访问相同记录_1 {
}
/**
 * 2. MySQL并发事务访问相同记录
 * 并发事务访问相同记录的情况大致可以划分为3种:
 * 2.1 读-读 情况   没任何问题
 * 读-读情况，    即并发事务相继读取相同的记录。
 * 读取操作本身不会对记录有任何影响，并不会引起什么问题，所以允许这种情况的发生。
 *
 * 2.2 写-写 情况
 * 写-写情况，   即并发事务相继对相同的记录做出改动。
 * 在这种情况下会发生脏写的问题，任何一种隔离级别都不允许这种问题的发生。
 * 当某个事务要对某条纪律执行时，会生成一个锁结构，
 * 在锁结构里有很多信息，为了简化理解， 只把两个比较重要的属性拿了出来:
 * ●trx信息:代表这个锁结构是哪个事务生成的。
 * ●is.waiting: 代表当前事务是否在等待。
 *              最初是false 表示没事务占用
 *
 * 2.3读-写或写-读情况
 * 读-写或写-读，即一个事务进行读取操作，另一个进行改动操作。
 * 这种情况下可能发生脏读、不可重复读、幻读的问题。
 * 各个数据库厂商对SQL标准的支持都可能不一样。
 * 比如MySQL在REPEATABLE READ 隔离级别.上就已经解决了幻读问题。
 *
 * 2.4并发问题的解决方案
 * 怎么解决脏读、不可重复读、 幻读这些问题呢?其实有两种可选的解决方案:
 * ●方案一:读操作利用多版本并发控制(MVCC， 下章讲解)，写操作进行加锁。
 * 所谓的MVCC，就是生成一个ReadView，
 * 通过ReadView找到符合条件的记录版本(历史版本由undo日志构建)。
 * 查询语句只能读到在生成ReadView之前已提交事务所做的更改，
 * 在生成ReadView之前未提交的事务或者之后才开启的事务所做的更改是看不到的。
 * 而写操作肯定针对的是最新版本的记录，读记录的历史版本和改动记录
 * 的最新版本本身并不冲突，也就是采用MVCC时，读-写操作并不冲突。
 * ●方案二:读、写操作都采用加锁的方式。
 *   脏读和不可重复读都可以再加锁的情况下避免，因为操作的都是同一数据
 *   但是幻读是插入，无法进行对不存在的数据加锁，所以不可避免
 *
 * ●小结对比发现:
 * 。采用MVCC方式的话，读-写操作彼此并不冲突，性能更高。
 * 。采用加锁方式的话， 读-写操作彼此需要排队执行，影响性能。
 * -般情况下我们当然愿意采用MVCC来解决读-写操作并发执行的问题,但是业务在某些特殊情况下，要求必
 * 须采用加锁的方式执行。下面就讲解下MySQL中不同类别的锁。
 *
 *
 *
 */
